using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace EchoFramework
{
    /// <summary>
    /// 事件管理器
    /// </summary>
    public class EventManager : Singleton<EventManager>
    {
        /// <summary>
        /// 所有事件存储的字典
        /// key:事件类型
        /// value:事件类型对应的Action列表
        /// </summary>
        private Dictionary<int, List<Action<EventObject>>> eventDict;

        /// <summary>
        /// 事件中心初始化
        /// </summary>
        public override void OnInit()
        {
            base.OnInit();
            eventDict = new Dictionary<int, List<Action<EventObject>>>();
        }

        /// <summary>
        /// 注册事件
        /// </summary>
        /// <param name="eventTypeEnum">事件类型</param>
        /// <param name="eventAction">事件行为</param>
        public void Register(EventTypeEnum eventTypeEnum, Action<EventObject> eventAction)
        {
            Register((int)eventTypeEnum, eventAction);
        }

        /// <summary>
        /// 注册事件
        /// </summary>
        /// <param name="eventType">事件类型(int)</param>
        /// <param name="eventAction">事件Action</param>
        public void Register(int eventType, Action<EventObject> eventAction)
        {
            List<Action<EventObject>> actionList;
            if (eventDict.TryGetValue(eventType, out actionList))
            {
                if (!actionList.Contains(eventAction))
                {
                    actionList.Add(eventAction);
                }
            }
            else
            {
                actionList = new List<Action<EventObject>>();
                actionList.Add(eventAction);
                eventDict.Add(eventType, actionList);
            }
        }

        /// <summary>
        /// 执行事件
        /// </summary>
        /// <param name="eventTypeEnum">事件类型</param>
        /// <param name="objs">可变参数</param>
        public void Execute(EventTypeEnum eventTypeEnum, params object[] objs)
        {
            Execute((int)eventTypeEnum, objs); 
        }

        /// <summary>
        /// 执行事件
        /// </summary>
        /// <param name="eventType">事件类型(int)</param>
        /// <param name="objs">可变参数</param>
        public void Execute(int eventType, params object[] objs)
        {
            List<Action<EventObject>> actionList;
            if (!eventDict.TryGetValue(eventType, out actionList))
            {
                return;
            }

            Action<EventObject> eventAction = null;
            for (int i = 0; i < actionList.Count; i++)
            {
                eventAction = actionList[i];
                try
                {
                    eventAction(new EventObject(objs));
                }
                catch (Exception e)
                {
                    GameLogger.LogWarning(string.Format("执行事件类型{0}存在问题！", eventType));
                    GameLogger.LogWarning(e);
                }
            }
        }

        /// <summary>
        /// 移除事件类型中的单个事件
        /// </summary>
        /// <param name="eventTypeEnum">事件类型</param>
        /// <param name="eventAction">事件Action</param>
        public void UnRegister(EventTypeEnum eventTypeEnum, Action<EventObject> eventAction)
        {
            UnRegiseter((int)eventTypeEnum, eventAction);
        }

        /// <summary>
        /// 移除事件类型中的单个事件
        /// </summary>
        /// <param name="eventType">事件类型(int)</param>
        /// <param name="eventAction">事件Action</param>
        public void UnRegiseter(int eventType, Action<EventObject> eventAction)
        {
            List<Action<EventObject>> eventList;
            if (eventDict.TryGetValue(eventType, out eventList))
            {
                eventList.Remove(eventAction);
            }
        }

        /// <summary>
        /// 移除对应事件类型的所有事件Action
        /// </summary>
        /// <param name="eventTypeEnum">事件类型</param>
        public void UnRegisterAllAction(EventTypeEnum eventTypeEnum)
        {
            UnRegisterAllAction((int)eventTypeEnum);
        }

        /// <summary>
        /// 移除对应事件类型的所有事件Action
        /// </summary>
        /// <param name="eventType">事件类型</param>
        public void UnRegisterAllAction(int eventType)
        {
            List<Action<EventObject>> eventList;
            if (eventDict.TryGetValue(eventType, out eventList))
            {
                eventList.Clear();
            }
        }

        /// <summary>
        /// 清空字典中所有事件
        /// </summary>
        public void Clear()
        {
            Dictionary<int, List<Action<EventObject>>>.Enumerator iter = eventDict.GetEnumerator();
            while (iter.MoveNext())
            {
                UnRegisterAllAction(iter.Current.Key);
            }
            iter.Dispose();
        }
    }
}
